<template>
  <div class="system-auth-page">
    <!-- 用户授权 -->
     
    <!-- 角色授权 -->
    <el-space wrap class="system-auth-space">
      <el-card class="system-auth-space-card">
        <template #header>
          <div>角色列表</div>
        </template>
        <div class="left-panel">
          <ul class="left-role-list">
            <li
              v-for="item in roleList"
              :key="item.roleId"
              class="list-item role-list-item list-item-hover"
              :class="{
                'active-list-item': curRole?.roleCode === item.roleCode
              }"
              @click="handleRoleClick(item)"
            >
              <el-text class="mx-1">
                {{ item.roleName }}（{{ item.roleCode }}）
              </el-text>
            </li>
          </ul>
          <el-text class="mx-1" type="info" v-if="roleList.length === 0">
            暂无可用的角色，请
            <router-link to="/system/role" c-blue>添加角色</router-link>
          </el-text>
        </div>
      </el-card>
      <el-card ml-8px class="system-auth-space-card">
        <template #header>
          <div>菜单管理</div>
        </template>
        <div class="menu-tree-box">
          <el-tree
            ref="menuTreeRef"
            :data="menuTreeData"
            show-checkbox
            node-key="menuId"
            default-expand-all
            :props="defaultProps"
            :expand-on-click-node="false"
            :check-on-click-node="true"
            @check="checkCurrMenuHandler"
            @check-change="checkChangeCurrMenuHandler"
          >
            <template #default="{ data }">
              <el-text class="mx-1">{{ data.menuName }}</el-text>
            </template>
          </el-tree>
        </div>
      </el-card>
      <el-card ml-8px class="system-auth-space-card">
        <template #header>
          <div>权限列表</div>
        </template>
        <div class="left-panel" style="width: 600px">
          <el-checkbox-group
            v-model="selectAuthoritiesArr"
            @change="checkAuthoritiesHandler"
          >
            <div
              v-for="item in authoritiesTreeData"
              :key="'auth-operation-box-' + item.menuId"
            >
              <div class="mt-16px mb-16px h-auto">
                <el-text class="mx-1">{{ item.menuName }}</el-text>
              </div>
              <div v-if="item.children && item.children.length">
                <ul class="left-role-list">
                  <li
                    v-for="operate in item.children"
                    :key="'auth-operation-li' + operate.menuId"
                    class="list-item"
                  >
                    <el-checkbox
                      :key="'auth-operation-checkbox' + operate.menuId"
                      :value="operate.menuId"
                      border
                    >
                      {{ operate.menuName }}
                    </el-checkbox>
                  </li>
                </ul>
              </div>
              <el-text class="mx-1" type="info" v-else>
                无数据，请进行
                <router-link to="/system/menu" c-blue>权限添加</router-link>
              </el-text>
            </div>
          </el-checkbox-group>
        </div>
      </el-card>
    </el-space>
    <el-card class="system-submit-card">
      <el-button type="default" @click="clearRolesMenu()" size="large"
        >清空</el-button
      >
      <el-button type="primary" @click="submitRolesMenu()" size="large"
        >提交</el-button
      >
    </el-card>
  </div>
</template>

<script setup lang="ts">
import { getMenuByRoleId, updateMenuByRoleId } from "@/api/auth"
import { getMenuInfo } from "@/api/menu"
import { getRoleInfo } from "@/api/role"
import type { Role, RoleMenus, Menu } from "@/types/system"
import { buildTree } from "@/utils/tools"
import { ElMessage } from "element-plus"

const defaultProps = {
  children: "children",
  label: "menuName"
}
const roleList = ref<Role[]>([])
const menuTreeData = ref<any[]>([])
const authoritiesTreeData = ref<any[]>([])
const menuTreeRef = ref<any>(null)
const roleMenusData = ref<RoleMenus>({
  roleCode: "",
  menus: [],
  authorities: []
})
const selectMenuArr = ref<number[]>([])
const selectAuthoritiesArr = ref<number[]>([])
const roleLoading = ref(false)
const curRole = ref<Role | null>(null)

// 获取角色信息(param可选)
const getRoleList = async () => {
  roleLoading.value = true
  try {
    const res = await getRoleInfo({})
    roleList.value = res.data.rows
  } catch (error) {
    console.error(error) // eslint-disable-line
  } finally {
    roleLoading.value = false
  }
}
// 获取菜单和操作权限信息
const getMenuList = async () => {
  const res = await getMenuInfo({})
  if (res.code !== 0) {
    ElMessage.error(res.msg)
    return
  }
  // 处理数据
  if (res.data.rows.length === 0) {
    ElMessage.warning("暂无菜单数据，请先添加菜单")
    return
  }

  let menuList = res.data.rows.filter((item: any) => item.menuType !== "2")
  const operateList = res.data.rows.filter(
    (item: any) => item.menuType === "1" || item.menuType === "2"
  )
  menuList = menuList.map((item: any) => {
    item.value = item.menuId
    return item
  })
  const tempMenuTreeData = [
    {
      menuId: 0,
      value: 0,
      menuName: "菜单列表",
      children: buildTree(menuList, "menuId", "parentId")
    }
  ]

  menuTreeData.value = tempMenuTreeData
  authoritiesTreeData.value = buildTree(operateList, "menuId", "parentId")
}
// 获取当前角色的菜单权限
const getMenuByRole = async (roleId: number) => {
  const res = await getMenuByRoleId({ roleId })
  if (res.code !== 0) {
    ElMessage.error(res.msg)
    return
  }
  roleMenusData.value.menus = res.data.rows.filter(
    // 取菜单类型的数据
    (item: any) => item.menuType === "1"
  )
  roleMenusData.value.authorities = res.data.rows.filter(
    // 取操作权限类型的数据
    (item: any) => item.menuType === "2"
  )
  selectMenuArr.value = roleMenusData.value.menus.map(
    (item: any) => item.menuId
  )
  const tempselectAuthoritiesList = roleMenusData.value.authorities.map(
    (item: any) => item.menuId
  )
  setCheckedKeys(selectMenuArr.value)
  setAuthoritiesChecked(tempselectAuthoritiesList)
}
// 处理角色点击事件
const handleRoleClick = async (item: Role) => {
  console.log("当前选中的角色：", item)
  curRole.value = item
  setCheckedKeys([])
  setAuthoritiesChecked([])
  await nextTick()
  if (item.roleId !== undefined) {
    getMenuByRole(item.roleId)
  }
}
// 设置/清空树形菜单勾选
const setCheckedKeys = (keys: number[]) => {
  if (menuTreeRef.value) {
    menuTreeRef.value!.setCheckedKeys(keys, false)
  }
}
// 设置/清空操作权限复选框勾选
const setAuthoritiesChecked = (keys: number[]) => {
  selectAuthoritiesArr.value = keys || []
}
// 处理树形菜单勾选变化事件
const checkChangeCurrMenuHandler = (
  data: Menu,
  checked: boolean,
  indeterminate: boolean
) => {
  console.log("树形菜单勾选变化：", data, checked, indeterminate)
  // 如果是全选或取消全选，则清空当前选择
  // if (checked) {
  //   selectMenuArr.value = menuTreeRef.value!.getCheckedKeys()
  // } else {
  //   selectMenuArr.value = []
  // }
}
// 处理树形勾选事件
const checkCurrMenuHandler = (data: Menu, checkedObj: any) => {
  console.log("当前勾选的菜单数据：", checkedObj.checkedKeys)
  selectMenuArr.value = checkedObj.checkedKeys
}
// 处理操作权限复选框勾选事件
const checkAuthoritiesHandler = (data: any) => {
  console.log("当前勾选的操作权限数据：", data)
}
// 提交角色菜单权限
const submitRolesMenu = () => {
  if (!curRole.value) {
    ElMessage.warning("请先选择一个角色")
    return
  }
  if (
    selectMenuArr.value.length === 0 &&
    selectAuthoritiesArr.value.length === 0
  ) {
    ElMessage.warning("请至少选择一个菜单或权限")
    return
  }

  const postData = {
    roleId: curRole.value?.roleId,
    menuIds: [...selectMenuArr.value, ...selectAuthoritiesArr.value]
  }
  updateMenuByRoleId(postData)
    .then((res) => {
      if (res.code === 0) {
        ElMessage.success("角色菜单权限更新成功")
        // 重置当前角色
        clearRolesMenu()
      } else {
        ElMessage.error(res.msg)
      }
    })
    .catch((error) => {
      console.error("提交角色菜单权限失败：", error) // eslint-disable-line
      ElMessage.error("提交角色菜单权限失败，请稍后重试")
    })
}
// 清空角色菜单权限
const clearRolesMenu = () => {
  curRole.value = null
  selectMenuArr.value = []
  selectAuthoritiesArr.value = []
  setCheckedKeys([])
  setAuthoritiesChecked([])
}
// 组件挂载后获取角色信息
onMounted(() => {
  getRoleList()
  getMenuList()
})
</script>

<style lang="scss">
.system-auth-page {
  @apply flex relative h-full;
  .system-auth-space {
    @apply w-full;
    height: calc(100% - 100px);
    .el-space__item {
      @apply h-full;
    }
    .system-auth-space-card {
      @apply h-full;
    }
    .left-panel {
      @apply w-300px h-full overflow-y-auto;
      .left-panel-title {
        @apply text-16px p-8px border-b-solid border-1 border-gray-300;
      }
      .left-role-list {
        @apply overflow-y-auto;
        .list-item {
          @apply p-8px cursor-pointer inline-block;
        }
        .role-list-item {
          @apply block;
        }
        .list-item-hover {
          &:hover {
            @apply bg-gray-200;
          }
        }
        .active-list-item {
          @apply bg-gray-200;
          span {
            @apply text-blue-500;
          }
        }
      }
    }
    .menu-tree-box {
      @apply w-300px h-full overflow-y-auto;
      .custom-tree-node {
        @apply flex-1 flex items-center justify-between pr-8px;
      }
    }
  }
  .system-submit-card {
    @apply w-100% absolute text-center bottom-0 left-0;
  }
}
</style>
